import java.io.File;
import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Main  {

    private static final int NUMBER_OF_THREADS = 3;
    private static File file = new File("hello.txt");
    private static ArrayList<Future<byte[]>> taskList = new ArrayList<Future<byte[]>>(NUMBER_OF_THREADS);
    private static int fileSize = (int) file.length();

    public static void main(String[] args) throws Exception {
        readFile();
        byte[] fileContent = constructContent();
        String text = new String(fileContent);
        System.out.println(text);

    }

    protected static void readFile() {
        ExecutorService pool = Executors.newFixedThreadPool(NUMBER_OF_THREADS);
        try {
            int partSize = fileSize / NUMBER_OF_THREADS;
            int offset;

            for (int i = 0; i < NUMBER_OF_THREADS; i++) {
                offset = partSize * i;
                partSize = (i == NUMBER_OF_THREADS - 1) ? fileSize - partSize * i : partSize;
                Callable<byte[]> readTask = new ReadTask(file, partSize, offset);
                taskList.add(pool.submit(readTask));
            }
        } finally {
            pool.shutdown();
        }
    }

    private static byte[] constructContent() throws Exception{
        byte[] result = new byte[fileSize];
        int counter = 0;
        for(Future<byte[]> task: taskList) {
            byte[] temp = task.get();
            for (byte b: temp){
                result[counter++] = b;
            }
        }

        return result;
    }
}
